home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-10-05 | 57.9 KB | 2,292 lines |
- This is an official patch to nn release 6.4
- -------------------------------------------
-
- PATCH #11
-
- Priority: HIGH
-
-
- This patch fixes a syntax error introduced in patch #10 which causes
- term.c not to compile on some systems. It also fixes a nasty bug in
- the article header sorting which could provoke a crash in qsort;
- unfortunately the fix involves changing the interpretation of the
- subject-match-limit variable:
-
- ===================================================================
-
- The subject-match-limit variable is now a simple compare only first
- "length" characters limit whereas before it was only used if one
- subject was a true suffix of another subject. Unfortunately, the old
- interpretation made the sorting non-deterministic and it could cause
- qsort() to crash. The default value is now changed to 256 effectively
- disabling the match-limit unless explicitly set to a lower limit.
-
- Thanks to Paul Eggert for a detailed analysis on this problem.
-
- ===================================================================
-
- This patch also changes the splitting of folders in a way which is not
- backwards compatible: When splitting a folder (e.g. G +folder), nn
- will now determine the format of the folder (mail, mmdf, standard)
- from the *first* article in the folder, and the rest of the folder is
- split according to this format. (Thanks to Bernd Wechner for a lot of
- patches to the folder and digest code).
-
- This may cause problems with current folders which are a mixture of
- different formats; such folders must be manually reformatted to use
- only a single format.
-
- To ensure that folders are used properly, the save-full and save-short
- commands will now append articles to an existing folder using the
- current format of the folder (determined from the first article).
- Consequently, the mmdf-format and mail-format variables are now only
- used to determine the type to use for new folders.
-
- ===================================================================
-
- Notice: Updates to the manual for the new features are postponed to
- the next patch to keep this patch at a reasonable size.
-
- As usual, all changes are described in the updated RELEASE_NOTES file
- (read that for more details about this patch). Thanks to all who
- reported bugs and provided fixes.
-
- To apply this patch, use nn's :patch command, or run this command from
- the shell in the root of the nn source tree:
- patch -p0 < this-article
-
- Then run "make all" and "./inst u".
-
- ++Kim Storm
-
- ===================================================================
-
- *** ./LAST/admin.c Tue Sep 18 12:44:49 1990
- --- admin.c Wed Sep 19 18:40:59 1990
- ***************
- *** 781,787 ****
- char command[FILENAME*2];
- char *rmprog;
-
- ! if (!file_exist(news_active, "w")) {
- printf("Not privileged to run rmgroup\n");
- return;
- }
- --- 781,787 ----
- char command[FILENAME*2];
- char *rmprog;
-
- ! if (user_id != 0 && !file_exist(news_active, "w")) {
- printf("Not privileged to run rmgroup\n");
- return;
- }
- *** ./LAST/aux.sh Mon Jul 9 17:59:52 1990
- --- aux.sh Tue Sep 25 16:08:24 1990
- ***************
- *** 334,343 ****
- follow|post)
- {
- if ${POST_PIPE} ; then
- ! $POST < $FINAL
- x=$?
- else
- ! $POST $FINAL
- x=$?
- fi
- case $x in
- --- 334,343 ----
- follow|post)
- {
- if ${POST_PIPE} ; then
- ! $POST < $FINAL 2>&1
- x=$?
- else
- ! $POST $FINAL 2>&1
- x=$?
- fi
- case $x in
- ***************
- *** 344,350 ****
- 0) sleep 60 ;;
- *) echo $INEWS failed ;;
- esac
- ! } | fgrep -v "mailing your article to"
- ;;
-
- *)
- --- 344,355 ----
- 0) sleep 60 ;;
- *) echo $INEWS failed ;;
- esac
- ! } | sed \
- ! -e "/spooled for later processing/d" \
- ! -e "/problem has been taken care of/d" \
- ! -e "/mailing your article to/d" \
- ! -e "/being mailed to/d" \
- ! -e "/is moderated/d"
- ;;
-
- *)
- *** ./LAST/conf/m-symmetry.h Sat Mar 31 23:12:50 1990
- --- conf/m-symmetry.h Thu Aug 23 11:41:47 1990
- ***************
- *** 20,25 ****
- --- 20,28 ----
- #define NO_VARARGS
- #define STRCSPN
-
- + /* enable parallel make hook in xmakefile */
- + #define PARALLEL_MAKE
- +
- /*
- * Not in network byte order on the 386
- */
- *** ./LAST/conf/s-pyramid.h Sat Mar 31 23:13:02 1990
- --- conf/s-pyramid.h Mon Sep 24 13:14:00 1990
- ***************
- *** 9,13 ****
- --- 9,17 ----
-
- extern FILE *popen();
-
- + /* The sysV shell has test built-in */
- + #undef SHELL
- + #define SHELL "/.attbin/sh"
- +
- #undef MAILX
- #define MAILX "/usr/.ucbucb/Mail" /* BSD */
- *** ./LAST/db.c Tue Sep 18 12:44:53 1990
- --- db.c Thu Sep 20 18:01:05 1990
- ***************
- *** 22,27 ****
- --- 22,29 ----
-
- export int reread_groups_file = 0; /* nnmaster -G */
-
- + export int check_group_access = 0;
- +
- export data_header db_hdr;
- export data_dynamic_data db_data;
-
- ***************
- *** 97,102 ****
- --- 99,109 ----
-
- /* client */
- if (gh->master_flag & M_NO_DIRECTORY) return 0;
- +
- + if (check_group_access && !use_nntp) {
- + *p = NUL;
- + if (file_exist(group_path_name, "dxr") == 0) return 0;
- + }
-
- *p++ = '/';
- *p = NUL;
- *** ./LAST/digest.c Thu Jul 19 18:12:10 1990
- --- digest.c Fri Oct 5 18:12:35 1990
- ***************
- *** 2,7 ****
- --- 2,11 ----
- * (c) Copyright 1990, Kim Fabricius Storm. All rights reserved.
- *
- * Digest article handling
- + *
- + * The code to do the selective parsing of mail and mmdf formats,
- + * mail from lines and determining folder types is based on patches
- + * contributed by Bernd Wechner (bernd@bhpcpd.kembla.oz.au).
- */
-
- #include "config.h"
- ***************
- *** 8,13 ****
- --- 12,19 ----
- #include "news.h"
- #include "debug.h"
-
- + export int strict_from_parse = 2;
- +
- #ifdef DG_TEST
-
- #define TEST(fmt, x, y) if (Debug & DG_TEST) printf(fmt, x, y)
- ***************
- *** 49,59 ****
- --- 55,196 ----
-
-
- /*
- + * is_mail_from_line - Is this a legal unix mail "From " line?
- + *
- + * Given a line of input will check to see if it matches the standard
- + * unix mail "from " header format. Returns 0 if it does and <0 if not.
- + *
- + * The check may be very lax or very strict depending upon
- + * the value of "strict-mail-from-parse":
- + *
- + * 0 - Lax, checks only for the string "From ".
- + * 1 - Strict, checks that the correct number of fields are present.
- + * 2 - Very strict, also checks that each field contains a legal value.
- + *
- + * Assumptions: Not having the definitive unix mailbox reference I have
- + * assumed that unix mailbox headers follow this format:
- + *
- + * From <person> <date> <garbage>
- + *
- + * Where <person> is the address of the sender, being an ordinary
- + * string with no white space imbedded in it, and <date> is the date of
- + * posting, in ctime(3C) format.
- + *
- + * This would, on the face of it, seem valid. I (Bernd) have yet to find a
- + * unix mailbox header which doesn't follow this format.
- + *
- + * From: Bernd Wechner (bernd@bhpcpd.kembla.oz.au)
- + * Obfuscated by: KFS (as usual)
- + */
- +
- + #define MAX_FIELDS 10
- +
- + static char legal_day[] = "SunMonTueWedThuFriSat";
- + static char legal_month[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
- + static int legal_numbers[] = { 1, 31, 0, 23, 0, 59, 0, 60, 1969, 2199 };
- +
- + int is_mail_from_line(line, namebuf)
- + char *line; /* Line of text to be checked */
- + char *namebuf; /* Optional buffer to place packed sender info */
- + {
- + char *fields[MAX_FIELDS];
- + char *sender_tail;
- + register char *lp, **fp;
- + register int n, i;
- +
- + if (strncmp(line, "From ", 5)) return -100;
- + if (strict_from_parse == 0) return 0;
- +
- + lp = line + 5;
- + /* sender day mon dd hh:mm:ss year */
- + for (n = 0, fp = fields; n < MAX_FIELDS; n++) {
- + while (*lp && *lp != NL && isascii(*lp) && isspace(*lp)) lp++;
- + if (*lp == NUL || *lp == NL) break;
- + *fp++ = lp;
- + while (*lp && isascii(*lp) && !isspace(*lp))
- + if (*lp++ == ':' && (n == 4 || n == 5)) break;
- + if (n == 0) sender_tail = lp;
- + }
- +
- + if (n < 8) return -200-n;
- +
- + fp = fields;
- +
- + if (namebuf != NULL) {
- + char x = *sender_tail;
- + *sender_tail = NUL;
- + pack_name(namebuf, *fp, NAME_LENGTH);
- + *sender_tail = x;
- + }
- +
- + if (strict_from_parse == 1) return 0;
- +
- + fp++;
- + for (i = 0; i < 21; i += 3)
- + if (strncmp(*fp, &legal_day[i], 3) == 0) break;
- + if (i == 21) return -1;
- +
- + fp++;
- + for (i = 0; i < 36; i += 3)
- + if (strncmp(*fp, &legal_month[i], 3) == 0) break;
- + if (i == 36) return -2;
- +
- + for (i = 0; i < 10; i += 2) {
- + lp = *++fp;
- + if (!isdigit(*lp)) return -20-i;
- + n = atoi(lp);
- + if (n < legal_numbers[i] || legal_numbers[i+1] < n) return -10-i;
- + }
- + return 0;
- + }
- +
- + /*
- * expect that f is positioned at header of an article
- */
-
- static int is_mmdf_folder = 0;
- + static int is_mail_folder = 0;
-
- + /*
- + * get_folder_type
- + *
- + * Given a file descriptor f, will check what type of folder it is.
- + * Must be called at zero offset and caller must reposition if necessary.
- + * Side-effects: sets is_mail_folder, is_mmdf_folder, and current_folder_type.
- + * Return values:
- + * -1: folder is empty,
- + * 0: normal digest,
- + * 1: UNIX mail format
- + * 2: MMDF format
- + */
- +
- + export int current_folder_type;
- +
- + int get_folder_type(f)
- + FILE *f;
- + {
- + char line[1024];
- + int siz;
- +
- + is_mail_folder = 0;
- + is_mmdf_folder = 0;
- +
- + if (fgets(line, 1024, f) == NULL)
- + return current_folder_type = -1;
- +
- + if (strncmp(line, "\001\001\001\001\n", 5) == 0) {
- + is_mmdf_folder = 1;
- + return current_folder_type = 2;
- + }
- +
- + if (is_mail_from_line(line, (char *)NULL) == 0) {
- + is_mail_folder = 1;
- + return current_folder_type = 1;
- + }
- +
- + return current_folder_type = 0;
- + }
- +
- get_digest_article(f, hdrbuf)
- FILE *f;
- news_header_buffer hdrbuf;
- ***************
- *** 183,198 ****
-
- TEST("\n>>%-.50s ==>>", line, 0);
-
- ! if (line[0] == '\001' && strcmp(line, "\001\001\001\001\n") == 0) {
- digest.dg_lpos = backup_p[backup_index];
- - if (!is_mmdf_folder) fseek(f, digest.dg_lpos, 0);
- --digest.dg_lines;
- - is_mmdf_folder = 0;
- return (digest.dg_lines <= 0) ? -1 : 1;
- }
-
- - if (is_mmdf_folder) goto next_line;
- -
- for (cp = line; *cp && isascii(*cp) && isspace(*cp); cp++);
-
- if (*cp == NUL) {
- --- 320,335 ----
-
- TEST("\n>>%-.50s ==>>", line, 0);
-
- ! if (is_mmdf_folder) {
- ! /* in an mmdf folder we simply look for the next ^A^A^A^A line */
- ! if (line[0] != '\001' || strcmp(line, "\001\001\001\001\n"))
- ! goto next_line;
- !
- digest.dg_lpos = backup_p[backup_index];
- --digest.dg_lines;
- return (digest.dg_lines <= 0) ? -1 : 1;
- }
-
- for (cp = line; *cp && isascii(*cp) && isspace(*cp); cp++);
-
- if (*cp == NUL) {
- ***************
- *** 201,206 ****
- --- 338,353 ----
- goto next_line;
- }
-
- + if (is_mail_folder) {
- + /* in a mail folder we simply look for the next "From " line */
- + if (line[0] != 'F' || is_mail_from_line(line, (char *)NULL) < 0)
- + goto next_line;
- +
- + line_type[backup_index] = LN_HEADER;
- + fseek(f, backup_p[backup_index], 0);
- + goto found_mail_header;
- + }
- +
- blanks = cp - line;
-
- if (*cp == '-') {
- ***************
- *** 242,290 ****
- goto next_line;
- }
-
- ! if (blanks == 0) {
- ! if (dg_hdr_field(line, 0)) {
- ! TEST("HEADER", 0, 0);
-
- ! line_type[backup_index] = LN_HEADER;
- ! if (++more_header_lines < MIN_HEADER_LINES)
- ! goto next_possible_header_line;
- !
- ! /* found block with MIN_HEADER_LINES */
- !
- ! /* search for beginning of header */
-
- ! TEST("\nSearch for start of header\n", 0, 0);
-
- ! for (;;) {
- ! fseek(f, backup_p[backup_index], 0);
- ! --digest.dg_lines;
- ! if (--backup_count == 0) break;
- ! decrease_index();
- ! if ((line_type[backup_index] & (LN_HEADER | LN_TEXT)) == 0)
- ! break;
- ! }
-
- ! if (digest.dg_lines == 0) {
- ! TEST("Skipped empty article\n", 0, 0);
- ! return -1;
- ! }
-
- ! for (;;) {
- ! digest.dg_lpos = backup_p[backup_index];
- ! if (--backup_count < 0) break;
- ! decrease_index();
- ! if ((line_type[backup_index] & (LN_BLANK | LN_DASHED)) == 0)
- ! break;
- ! --digest.dg_lines;
- ! }
-
- ! return (digest.dg_lines == 0) ? -1 : 1;
- ! }
- ! goto next_possible_header_line;
- }
-
- ! goto next_line;
- }
-
-
- --- 389,436 ----
- goto next_line;
- }
-
- ! if (blanks)
- ! goto next_line;
-
- ! if (!dg_hdr_field(line, 0))
- ! goto next_possible_header_line;
-
- ! TEST("HEADER", 0, 0);
-
- ! line_type[backup_index] = LN_HEADER;
- ! if (++more_header_lines < MIN_HEADER_LINES)
- ! goto next_possible_header_line;
-
- ! /* found block with MIN_HEADER_LINES */
-
- ! TEST("\nSearch for start of header\n", 0, 0);
-
- ! for (;;) {
- ! fseek(f, backup_p[backup_index], 0);
- ! --digest.dg_lines;
- ! if (--backup_count == 0) break;
- ! decrease_index();
- ! if ((line_type[backup_index] & (LN_HEADER | LN_TEXT)) == 0)
- ! break;
- ! }
- !
- ! if (digest.dg_lines == 0) {
- ! TEST("Skipped empty article\n", 0, 0);
- ! return -1;
- ! }
- !
- ! found_mail_header:
- !
- ! for (;;) {
- ! digest.dg_lpos = backup_p[backup_index];
- ! if (--backup_count < 0) break;
- ! decrease_index();
- ! if ((line_type[backup_index] & (LN_BLANK | LN_DASHED)) == 0)
- ! break;
- ! --digest.dg_lines;
- }
-
- ! return (digest.dg_lines == 0) ? -1 : 1;
- }
-
-
- ***************
- *** 307,312 ****
- --- 453,460 ----
- register char *lp;
- int all;
- {
- + static char *dummy;
- + static char namebuf[NAME_LENGTH+1];
-
- #define check(name, lgt, field) \
- if (isascii(lp[lgt]) && isspace(lp[lgt]) && strncmp(name, lp, lgt) == 0) {\
- ***************
- *** 320,331 ****
- switch (*lp++) {
-
- case '\001':
- ! if (!is_mmdf_folder && strncmp(lp, "\001\001\001\n", 4) == 0) {
- ! is_mmdf_folder = 1;
- ! digest.dg_hpos += 5;
- ! return NULL;
- ! }
- ! break;
-
- case 'D':
- case 'd':
- --- 468,478 ----
- switch (*lp++) {
-
- case '\001':
- ! /* In an mmdf folder ^A^A^A^A is skipped at beginning of header */
- ! if (!is_mmdf_folder) break;
- ! if (strncmp(lp, "\001\001\001\n", 4)) break;
- ! digest.dg_hpos += 5;
- ! return NULL;
-
- case 'D':
- case 'd':
- ***************
- *** 335,341 ****
- case 'F':
- case 'f':
- check("rom:", 4, dg_from);
- ! break;
-
- case 'R':
- case 'r':
- --- 482,493 ----
- case 'F':
- case 'f':
- check("rom:", 4, dg_from);
- ! if (!is_mail_folder) break;
- ! if (*--lp != 'F') break;
- ! if (is_mail_from_line(lp, namebuf) < 0) break;
- ! /* Store packed sender in dg_from here and return dummy to parser */
- ! if (digest.dg_from == NULL) digest.dg_from = namebuf;
- ! return &dummy;
-
- case 'R':
- case 'r':
- *** ./LAST/doc/RELEASE_NOTES Tue Sep 18 12:44:55 1990
- --- doc/RELEASE_NOTES Thu Oct 4 23:05:05 1990
- ***************
- *** 1163,1168 ****
- --- 1163,1230 ----
- than giving a new level-2 menu - or if it gave a level-2 menu
- it wasn't possible to repeat the command.
-
- + Prog: nn
- + Title: Patch 10 broke term.c on BSD based systems
- + From: too many to mention (sorry)!
- + Fixed: Patch #11 [term.c]
- +
- + Prog: nnadmin
- + Title: Root was sometimes denied permission to Z)ap (rmgroup) a group.
- + From: david@cs.uow.edu.au (David E A Wilson)
- + Fixed: Patch #11 [admin.c]
- +
- + Prog: nn
- + Title: Unsubscribed groups may be included by NEW in sequence.
- + From: avery@netcom.UUCP (Avery Colter)
- + Fixed: Patch #11 [sequence.c]
- +
- + Prog: nn
- + Title: 'V' {version} command not supported in reading mode.
- + From: msc@mtcchi.uucp (Michael S. Cross)
- + Fixed: Patch #11 [more.c]
- +
- + Prog: nn
- + Title: subject-match-limit confuses qsort() - may even dump core!
- + From: eggert@twinsun.com (Paul Eggert) + fix!!!!
- + kravitz%foxtail@ucsd.edu (Jody Kravitz)
- + Mark Nagel <nagel@ICS.UCI.EDU>
- + boutilie@motcid.UUCP (Eric Boutilier)
- + Nick Holloway <alfie@cs.warwick.ac.uk>
- + Fixed: Patch #11 [sort.c nn.1]
- +
- + Paul Eggert: It is possible to construct headers H,I,J for three
- + different articles such that H<I, I<J, and J<H. If subject-match-
- + limit is 1, then the following values for H,I,J cause the anomaly:
- + subject t_stamp
- + H ay 0
- + I a 1
- + J ax 2
- + The fix CHANGES the semantics of the subject-match-limit to be
- + a length check only.
- +
- + Prog: nn
- + Title: G some.group can only enter some.group once.
- + From: David Lesher <wb8foz@mthvax.cs.miami.edu>
- + liz@grian.cps.altadena.ca.us (Liz Allen-Mitchell)
- + Fixed: Patch #11 [group.c]
- +
- + Prog: nn
- + Title: Compressing an mmdf folder did not save in mmdf format.
- + From: Curtis Galloway <curtisg@sco.com> + fix
- + Fixed: Patch #11 [folder.c save.c]
- +
- + Prog: aux
- + Title: Some "good" messages from inews (various versions) are seen as fatal.
- + From: heiby@mcdchg.chg.mcd.mot.com (Ron Heiby) + fix
- + Nick Sayer <mrapple@quack.sac.ca.us> + fix
- + Fixed: Patch #11 [aux.sh]
- +
- + Prog: nnmaster
- + Title: The nnmaster should attempt to connect again (-r) rather than stop
- + in case of network errors when connecting to nntp server.
- + From: olson%anchor.esd@sgi.com (Dave Olson) + fixes
- + Fixed: Patch #11 [nntp.c global.c]
- +
-
- New features since initial 6.4.0 release
- ----------------------------------------
- ***************
- *** 1510,1512 ****
- --- 1572,1637 ----
- generation of Distribution: headers.
- From: KFS
- Added: Patch #10 [answer.c variable.c]
- +
- + Prog: nn
- + Title: ~user/ is now expanded in file names
- + From: bernd@bhpcpd.kembla.oz.au (Bernd Wechner) & KFS
- + Added: Patch #11 [folder.c]
- +
- + Prog: xmakefile
- + Title: Added support for Symmetry style parallel make
- + From: Kareth & Jaap Vermeulen
- + Added: Patch #11 [xmakefile conf/m-symmetry.h]
- +
- + Prog: nn
- + Title: If "check-group-access" is set, access to a group (including
- + the menu) is now prohibited.
- + From: KFS on request from David Paul Zimmerman <dpz@action.rutgers.edu>
- + Added: Patch #11 [db.c variable.c]
- +
- + Prog: nn
- + Title: A variable can now be locked, eg. "lock check-group-access" to
- + prevent a user from modifying the variable.
- + From: KFS
- + Added: Patch #11 [init.c variable.c]
- +
- + Prog: nn
- + Title: The init file "LIB/setup" is now loaded first independent of -I option.
- + From: KFS on request from David Paul Zimmerman <dpz@action.rutgers.edu>
- + Added: Patch #11 [init.c]
- +
- + Prog: nn
- + Title: nn will now look for a ".defaultnewsrc" on first startup in the
- + NEWS_LIB, CLIENT, and DB directories (var: initial-newsrc-file).
- + From: KFS on request from David Paul Zimmerman <dpz@action.rutgers.edu>
- + Added: Patch #11 [newsrc.c]
- +
- + Prog: nn
- + Title: Stricter splitting of folders and mail boxes.
- + From: bernd@bhpcpd.kembla.oz.au (Bernd Wechner) & KFS
- + Added: Patch #11 [folder.c digest.c variable.c]
- +
- + Folders are now split according to the format of the first article in
- + the folder, i.e. a folder is now either in "standard", "UNIX mail",
- + or MMDF format, and it is no longer possible to have "mixed" folders.
- +
- + Prog: nn
- + Title: Existing folders are now scanned to determine the proper format for
- + saved articles (unless the variable 'folder-format-check' is unset.)
- + From: KFS
- + Added: Patch #11 [save.c variable.c]
- +
- + This means that the variables 'mail-format' and 'mmdf-format'
- + are only used to determine the format of new folders, or if
- + 'folder-format-check' is off (if you know only one format is used).
- +
- + Prog: nn
- + Title: Improved rewriting of folders and mail boxes.
- + From: bernd@bhpcpd.kembla.oz.au (Bernd Wechner) & KFS
- + Added: Patch #11 [folder.c global.c variable.c]
- +
- + The backup folder is now located in the .nn directory (there is a new
- + variable backup-folder-path to control this), and a folder can now be
- + rewritten even if the directory is read only. The backup folder is
- + retained if the keep-backup-folder variable is set. A trace of the
- + compression process is now shown if trace-folder-packing is set.
- *** ./LAST/folder.c Mon Jul 16 17:38:41 1990
- --- folder.c Sat Sep 29 01:26:59 1990
- ***************
- *** 10,23 ****
- --- 10,64 ----
- #include "news.h"
- #include "term.h"
- #include "menu.h"
- + #include <pwd.h>
-
- + import char *home_directory;
- + import int current_folder_type;
- + import int use_mail_folders;
- + import int use_mmdf_folders;
- +
- export int dont_sort_folders = 0;
- export char *folder_directory = NULL;
- + export int folder_rewrite_trace = 1;
- + export char *backup_folder_path = "BackupFolder~";
- + export int keep_backup_folder = 1;
- + export int convert_folder_mode = 0; /* ignore folder's format on rewrite */
-
- import int fmt_linenum;
- import char *header_lines;
-
- /*
- + * expand ~[user][/...] form
- + * src ptr is advanced to last char of user name.
- + */
- +
- + static char *tilde_expansion(srcp, compl)
- + char **srcp;
- + int compl;
- + {
- + struct passwd *pwd, *getpwnam();
- + register char *name = *srcp;
- + register char *tail, x;
- +
- + tail = ++name; /* skip ~ */
- + while (*tail && isascii(*tail) && !isspace(*tail) && *tail != '/')
- + tail++;
- +
- + if (compl && *tail != '/') return NULL;
- + if (tail == name) return home_directory;
- +
- + *srcp = tail - 1;
- + x = *tail;
- + *tail = NUL;
- + pwd = getpwnam(name);
- + if (pwd == NULL && !compl)
- + msg("User %s not found", name);
- + *tail = x;
- +
- + return (pwd == NULL) ? NULL : pwd->pw_dir;
- + }
- +
- + /*
- * file name completion and expansion
- *
- * expand_mode bits:
- ***************
- *** 25,30 ****
- --- 66,72 ----
- * 2: don't expand $N
- * 4: don't expand any $? (but $(...) is expanded)
- * 8: don't complain about ~... (shell will do that)
- + * 10: doing filename completion
- */
-
-
- ***************
- *** 56,69 ****
- }
-
- if ((expand_mode & 1) && c == '~') {
- ! if (src[1] != '/') {
- ! if (expand_mode & 8) goto copy;
- ! msg("Can't handle ~user expansion (yet)");
- return 0;
- }
-
- - cp = home_directory;
- -
- cp_str:
- while (*cp) *dp++ = *cp++;
- if (dp[-1] != '/') *dp++ = '/';
- --- 98,107 ----
- }
-
- if ((expand_mode & 1) && c == '~') {
- ! if ((cp = tilde_expansion(&src, (expand_mode & 0x10))) == NULL) {
- return 0;
- }
-
- cp_str:
- while (*cp) *dp++ = *cp++;
- if (dp[-1] != '/') *dp++ = '/';
- ***************
- *** 187,193 ****
- if (*path == '|') return -1; /* no completion for pipes */
-
- if (*path == '+' || *path == '~') {
- ! if (!expand_file_name(nbuf, path, 1))
- return 0; /* no completions */
- } else
- strcpy(nbuf, path);
- --- 225,231 ----
- if (*path == '|') return -1; /* no completion for pipes */
-
- if (*path == '+' || *path == '~') {
- ! if (!expand_file_name(nbuf, path, 0x11))
- return 0; /* no completions */
- } else
- strcpy(nbuf, path);
- ***************
- *** 288,299 ****
- return ME_NO_REDRAW;
- }
-
- was_raw = no_raw();
- s_keyboard = 0;
-
- - printf("\rReading: %-.65s", path);
- - clrline();
- -
- current_group = &fake_group;
-
- mark_memory(&mem_marker);
- --- 326,349 ----
- return ME_NO_REDRAW;
- }
-
- + switch (get_folder_type(folder)) {
- + case 0:
- + msg("Reading: %-.65s", path); break;
- + case 1:
- + case 2:
- + msg("Reading %s folder: %-.50s",
- + current_folder_type==1 ? "mail" : "mmdf", path);
- + break;
- + default:
- + msg("Folder is empty");
- + fclose(folder);
- + return ME_NO_REDRAW;
- + }
- + rewind(folder);
- +
- was_raw = no_raw();
- s_keyboard = 0;
-
- current_group = &fake_group;
-
- mark_memory(&mem_marker);
- ***************
- *** 301,307 ****
- ah = alloc_art();
-
- more = 1;
- ! while (more && (more = get_digest_article(folder, dgbuf)) >= 0) {
- if (s_keyboard) break;
-
- ah->a_number = 0;
- --- 351,357 ----
- ah = alloc_art();
-
- more = 1;
- ! while (more && (more = get_digest_article(folder, dgbuf, 1)) >= 0) {
- if (s_keyboard) break;
-
- ah->a_number = 0;
- ***************
- *** 346,353 ****
-
- fclose(folder);
-
- - if (was_raw) raw();
- -
- if (s_keyboard) {
- menu_cmd = ME_NO_REDRAW;
- } else
- --- 396,401 ----
- ***************
- *** 381,387 ****
- }
- if (mode == 0 && cancel_count) {
- clrdisp();
- ! printf("Folder: %s\nFile: %s\n\n", folder_name, folder_file);
- if (cancel_count == n_articles)
- printf("Cancel all articles and remove folder? ");
- else
- --- 429,435 ----
- }
- if (mode == 0 && cancel_count) {
- clrdisp();
- ! printf("\rFolder: %s\n\rFile: %s\n\n\r", folder_name, folder_file);
- if (cancel_count == n_articles)
- printf("Cancel all articles and remove folder? ");
- else
- ***************
- *** 393,401 ****
- case 1:
- printf("\n\n");
- if (cancel_count == n_articles) {
- ! if (unlink(group_path_name) < 0) {
- ! printf("Could not unlink %s\n", group_path_name);
- ! sleep(3);
- }
- } else
- rewrite_folder();
- --- 441,450 ----
- case 1:
- printf("\n\n");
- if (cancel_count == n_articles) {
- ! if (unlink(group_path_name) < 0 &&
- ! truncate(group_path_name, (off_t)0) < 0) {
- ! printf("\rCould not unlink %s\n\r", group_path_name);
- ! any_key(0);
- }
- } else
- rewrite_folder();
- ***************
- *** 415,420 ****
- --- 464,471 ----
- header_lines = orig_hdr_lines;
- }
-
- + if (was_raw) raw();
- +
- return menu_cmd;
- }
-
- ***************
- *** 422,496 ****
- rewrite_folder()
- {
- register FILE *src, *dst;
- ! char oldfile[FILENAME], *sp;
- register int c;
- register long cnt;
- register article_header *ah, **ahp;
- register article_number n;
-
- ! if ((src = fopen(group_path_name, "r")) == NULL) {
- ! msg("Cannot open %s", group_path_name);
- ! return;
- }
-
- ! strcpy(oldfile, group_path_name);
- ! sp = strrchr(oldfile, '/');
- ! strcpy((sp == NULL ? oldfile : sp+1), "~OLD~FOLDER~");
- !
- ! unlink(oldfile);
- ! if (link(group_path_name, oldfile) < 0) goto move_error;
- ! if (unlink(group_path_name) < 0) {
- ! if (unlink(oldfile) == 0) goto move_error;
- ! printf("\n\n%s was linked to %s --- cannot proceed\n",
- ! group_path_name, oldfile);
- ! sleep(5);
- ! return;
- }
-
- ! if ((dst = fopen(group_path_name, "w")) == NULL) {
- fclose(src);
- goto move_back;
- }
-
- sort_articles(0);
-
- ! printf("Compressing folder..."); fl;
-
- for (ahp = articles, n = n_articles; --n >= 0; ahp++) {
- ah = *ahp;
- if (ah->attr == A_CANCEL) continue;
- fseek(src, ah->hpos, 0);
- ! cnt = ah->lpos - ah->hpos;
- while (--cnt >= 0) {
- if ((c = getc(src)) == EOF) break;
- putc(c, dst);
- }
- ! putc(NL, dst);
- }
- fclose(src);
- ! if (ferror(dst)) {
- ! fclose(dst);
- ! goto move_back;
- ! }
- ! unlink(oldfile);
- return;
-
- ! move_back:
- ! if (link(oldfile, group_path_name) == 0) {
- ! unlink(oldfile);
- ! printf("Cannot create new file -- Folder restored\n");
- ! sleep(2);
- ! } else {
- ! printf("Cannot create new file\n\nFolder saved in %s\n",
- ! oldfile);
- ! sleep(10);
- ! }
- ! return;
-
- ! move_error:
- ! fclose(src);
- ! printf("\n\nCannot move folder %s to %s\n",
- ! group_path_name, oldfile);
- ! sleep(3);
- ! return;
- }
- --- 473,540 ----
- rewrite_folder()
- {
- register FILE *src, *dst;
- ! char *oldfile, *sp;
- register int c;
- register long cnt;
- register article_header *ah, **ahp;
- register article_number n;
-
- ! if (strchr(backup_folder_path, '/'))
- ! oldfile = backup_folder_path;
- ! else
- ! oldfile = relative(nn_directory, backup_folder_path);
- !
- ! if (move_file(group_path_name, oldfile, 1) < 0) {
- ! printf("\r\n\nCannot backup folder in %s\n", oldfile);
- ! goto confirm;
- }
-
- ! if ((src = open_file(oldfile, OPEN_READ)) == NULL) {
- ! printf("\rCannot open %s\n\r", oldfile);
- ! goto move_back;
- }
-
- ! if ((dst = open_file(group_path_name, OPEN_CREATE)) == NULL) {
- fclose(src);
- + printf("\rCannot create %s\n\r", group_path_name);
- goto move_back;
- }
-
- sort_articles(0);
-
- ! printf("\rCompressing folder...\n\r"); fl;
- !
- ! get_folder_type(src);
-
- for (ahp = articles, n = n_articles; --n >= 0; ahp++) {
- ah = *ahp;
- + cnt = ah->lpos - ah->hpos;
- + if (folder_rewrite_trace)
- + printf("%s\t%s (%ld-%ld=%ld)\n\r",
- + ah->attr == A_CANCEL ? "CANCEL" : "KEEP",
- + ah->subject, (long)(ah->hpos), (long)(ah->lpos), cnt);
- if (ah->attr == A_CANCEL) continue;
- fseek(src, ah->hpos, 0);
- ! mailbox_format(dst, -1);
- while (--cnt >= 0) {
- if ((c = getc(src)) == EOF) break;
- putc(c, dst);
- }
- ! mailbox_format(dst, 0);
- }
- +
- fclose(src);
- ! if (fclose(dst) == EOF) goto move_back;
- ! if (!keep_backup_folder) unlink(oldfile);
- ! if (folder_rewrite_trace) goto confirm;
- return;
-
- ! move_back:
- ! if (move_file(oldfile, group_path_name, 2) == 0)
- ! printf("Cannot create new file -- Folder restored\n\r");
- ! else
- ! printf("Cannot create new file\n\n\rFolder saved in %s\n\r", oldfile);
-
- ! confirm:
- ! any_key(0);
- }
- *** ./LAST/global.c Tue Sep 18 12:44:57 1990
- --- global.c Fri Oct 5 18:23:21 1990
- ***************
- *** 39,44 ****
- --- 39,48 ----
-
- export char version_id[32];
-
- + #ifdef NNTP
- + export int use_nntp = 0; /* bool: t iff we use nntp */
- + #endif
- +
- export unsigned short user_eid;
- export unsigned short user_id, group_id;
- export int process_id;
- ***************
- *** 357,362 ****
- --- 361,387 ----
- return NULL;
- }
-
- + FILE *open_file_search_path(name, mode)
- + char *name;
- + int mode;
- + {
- + FILE *f;
- +
- + if (name == NULL) return NULL;
- +
- + if (*name == '/') return open_file(name, mode);
- +
- + f = NULL;
- + if (!use_nntp)
- + f = open_file(relative(news_lib_directory, name), OPEN_READ);
- + if (f == NULL)
- + f= open_file(relative(lib_directory, name), OPEN_READ);
- + if (f == NULL)
- + f = open_file(relative(db_directory, name), OPEN_READ);
- +
- + return f;
- + }
- +
- fgets_multi(buf, size, f)
- char *buf;
- int size;
- ***************
- *** 452,462 ****
- char *name;
- char *mode;
- {
- ! struct stat statb;
- extern int errno;
- int mask;
-
- ! if (stat(name, &statb)) return 0;
-
- if (mode == NULL) return statb.st_mtime;
-
- --- 477,487 ----
- char *name;
- char *mode;
- {
- ! static struct stat statb;
- extern int errno;
- int mask;
-
- ! if (name != NULL && stat(name, &statb)) return 0;
-
- if (mode == NULL) return statb.st_mtime;
-
- ***************
- *** 499,504 ****
- --- 524,637 ----
- return statb.st_mtime;
- }
-
- + /*
- + * copy_file: copy (or append) src file to dest file.
- + *
- + * Returns number of characters copied or an error code:
- + * -1: source file not found
- + * -2: cannot create destination
- + * -3: write error
- + */
- +
- + int32 copy_file(src, dest, append)
- + char *src, *dest;
- + int append;
- + {
- + register FILE *s, *d;
- + register int32 n = 0;
- + register int c;
- +
- + s = open_file(src, OPEN_READ);
- + if (s == NULL) return -1;
- +
- + d = open_file(dest, append ? OPEN_APPEND : OPEN_CREATE);
- + if (d == NULL) {
- + fclose(s);
- + return -2;
- + }
- +
- + n = 0;
- + while ((c = getc(s)) != EOF) {
- + putc(c, d);
- + n++;
- + }
- +
- + fclose(s);
- + if (fclose(d) == EOF) {
- + if (!append) unlink(dest);
- + return -3;
- + }
- + return n;
- + }
- +
- + /*
- + * move_file: move old file to new file, linking if possible.
- + *
- + * The third arg determines what is acceptable if the old file cannot be
- + * removed after copying to the new file:
- + * 0: must remove old, else remove new and fail,
- + * 1: must remove or truncate old, else remove new and fail,
- + * 2: just leave old if it cannot be removed or truncated.
- + *
- + * Returns positive value for success, negative for failure:
- + * 0: file renamed (link)
- + * 1: file copied, old removed
- + * 2: file copied, but old file is only truncated.
- + * 3: file copied, but old file still exist.
- + * -1: source file not found
- + * -2: cannot create destination
- + * -3: write error
- + * -4: cannot unlink/truncate old
- + * -5: cannot unlink new
- + * -6: cannot link old to new
- + * -9: messy situation: old and new linked on return (cannot happen?)
- + */
- +
- + move_file(old, new, may_keep_old)
- + char *old, *new;
- + int may_keep_old;
- + {
- + int32 n;
- +
- + if (file_exist(new, (char *)NULL)) {
- + if (file_exist((char *)NULL, "d"))
- + return -5;
- + if (unlink(new) < 0) /* careful - new may be directory ? */
- + switch (errno) {
- + case ENOENT:
- + break;
- + case EACCES:
- + if (file_exist((char *)NULL, "w")) goto do_copy;
- + default:
- + return -5;
- + }
- + }
- +
- + if (link(old, new) < 0)
- + switch (errno) {
- + case EACCES: /* can just as well try to copy */
- + case EXDEV:
- + goto do_copy;
- + default:
- + return -6;
- + }
- +
- + if (unlink(old) == 0)
- + return 0;
- +
- + /* we were able to link but not unlink old */
- + /* remove new, and attempt a copy instead */
- + if (unlink(new) < 0) return -9; /* cannot happen? */
- +
- + do_copy:
- + if ((n = copy_file(old, new, 0)) < 0) return n;
- + if (unlink(old) == 0) return 1;
- + if (may_keep_old)
- + if (n == 0 || truncate(old, (off_t)0) == 0) return 2;
- + if (may_keep_old == 2) return 3;
- + unlink(new);
- + return -4;
- + }
-
- #ifdef HAVE_SYSLOG
- #include <syslog.h>
- ***************
- *** 531,538 ****
- return 1;
- }
-
- ! static mail_sys_error(err)
- char *err;
- {
- FILE *f;
- char cmd[FILENAME*2];
- --- 664,672 ----
- return 1;
- }
-
- ! static mail_sys_error(err, isfatal)
- char *err;
- + int isfatal;
- {
- FILE *f;
- char cmd[FILENAME*2];
- ***************
- *** 541,553 ****
- strcpy(cmd, FATAL_ERROR_MAIL_CMD);
- #else
- #ifdef MAILX
- ! sprintf(cmd, "%s -s 'nnmaster fatal error' %s", MAILX, OWNER);
- #else
- sprintf(cmd, "mail %s", OWNER);
- #endif
- #endif
- if ((f = popen(cmd, "w")) == NULL) return;
- ! fprintf(f, "nnmaster terminated\n\nFatal system error:\n%s\n", err);
- pclose(f);
- }
-
- --- 675,690 ----
- strcpy(cmd, FATAL_ERROR_MAIL_CMD);
- #else
- #ifdef MAILX
- ! sprintf(cmd, "%s -s 'nnmaster %s' %s", MAILX,
- ! isfatal ? "fatal error" : "warning", OWNER);
- #else
- sprintf(cmd, "mail %s", OWNER);
- #endif
- #endif
- if ((f = popen(cmd, "w")) == NULL) return;
- ! fprintf(f, "nnmaster %s\n\n%system error:\n%s\n",
- ! isfatal ? "terminated" : "warning",
- ! isfatal ? "Fatal s" : "S", err);
- pclose(f);
- }
-
- ***************
- *** 570,576 ****
- end_vararg;
-
- if (who_am_i == I_AM_MASTER) {
- ! mail_sys_error(buf);
- if (dont_write_console) nn_exit(7);
- #ifndef HAVE_SYSLOG
- f = open_file("/dev/console", OPEN_CREATE);
- --- 707,713 ----
- end_vararg;
-
- if (who_am_i == I_AM_MASTER) {
- ! mail_sys_error(buf, 1);
- if (dont_write_console) nn_exit(7);
- #ifndef HAVE_SYSLOG
- f = open_file("/dev/console", OPEN_CREATE);
- ***************
- *** 587,592 ****
- --- 724,770 ----
- user_error("%s", buf);
- }
-
- + /*
- + * sys_warning: like sys_error but MASTER will return with -1
- + * instead of exit. Clients still terminate!
- + */
- +
- + /*VARARGS*/
- + sys_warning(va_alist)
- + va_dcl
- + {
- + char buf[512];
- + char *fmt;
- + FILE *f;
- + use_vararg;
- +
- + start_vararg;
- + enter_log('R', va_args1toN);
- + end_vararg;
- +
- + start_vararg;
- + fmt = va_arg1(char *);
- + vsprintf(buf, fmt, va_args2toN);
- + end_vararg;
- +
- + if (who_am_i != I_AM_MASTER)
- + user_error("%s", buf);
- +
- + mail_sys_error(buf, 0);
- + if (dont_write_console) return -1;
- + #ifndef HAVE_SYSLOG
- + if((f = open_file("/dev/console", OPEN_CREATE)) != NULL) {
- + fprintf(f, "\n\rNNMASTER WARNING\n\r%s\n\n\r", buf);
- + fclose(f);
- + }
- + #else /* HAVE_SYSLOG */
- + openlog("nnmaster", LOG_CONS, LOG_DAEMON);
- + syslog(LOG_ALERT, "%s", buf);
- + closelog();
- + #endif /* HAVE_SYSLOG */
- + return -1;
- + }
- +
- /*VARARGS*/
- log_entry(va_alist)
- va_dcl
- ***************
- *** 770,773 ****
- --- 948,976 ----
- path, mode, path);
- return system(command) != 0 ? -1 : 0;
- }
- + #endif
- +
- + #ifndef HAVE_TRUNCATE
- +
- + truncate(path, len)
- + char *path;
- + off_t len;
- + {
- + int fd;
- + struct stat st;
- +
- + if (len != 0)
- + sys_error("truncate(%s,%ld): non-zero length", path, (long)len);
- +
- + #ifdef O_TRUNC
- + fd = open(path, O_WRONLY | O_TRUNC);
- + #else
- + if (stat(path, &st) < 0) return -1;
- + fd = creat(path, st.st_mode & 07777);
- + #endif
- + if (fd < 0) return -1;
- + close(fd);
- + return 0;
- + }
- +
- #endif
- *** ./LAST/group.c Tue Sep 18 12:44:59 1990
- --- group.c Mon Sep 24 13:13:59 1990
- ***************
- *** 686,691 ****
- --- 686,692 ----
- msg("Group %s already active", gh->group_name);
- goto_return(ME_NO_REDRAW);
- }
- + if (o_cur_first < 0) o_cur_first = 0;
- gh->current_first = gh->last_db_article + 1;
- }
-
- *** ./LAST/init.c Thu Jul 19 18:12:14 1990
- --- init.c Thu Oct 4 19:04:47 1990
- ***************
- *** 178,183 ****
- --- 178,187 ----
- extern FILE *loc_seq_hook, *glob_seq_hook;
- char *next_arg;
-
- + in_init = 1;
- + load_init_file(relative(lib_directory, "setup"), (FILE **)NULL, 0);
- + in_init = 0;
- +
- if (first_arg && strncmp(first_arg, "-I", 2) == 0) {
- if (first_arg[2] == NUL) return;
- first_arg += 2;
- ***************
- *** 240,245 ****
- --- 244,250 ----
- "help", 4, 2,
- "load", 4, 0,
- "local", 5, 3,
- + "lock", 4, 3,
- "make", 4, -1,
- "make map ", 9, -2,
- "man", 3, 0,
- ***************
- *** 907,912 ****
- --- 912,923 ----
- CASE( "toggle" ) {
- if (argv(1) == NULL) goto stx_err;
- toggle_variable(argv(1));
- + break;
- + }
- +
- + CASE( "lock" ) {
- + if (argv(1) == NULL) goto stx_err;
- + lock_variable(argv(1));
- break;
- }
-
- *** ./LAST/man/nn.1.C Tue Sep 18 12:45:06 1990
- --- man/nn.1.C Fri Oct 5 18:43:05 1990
- ***************
- *** 1101,1113 ****
- .B n
- command).
- .TP
- ! \fBsubject-match-limit\fP \fIlength\fP (integer, default 20)
- ! If one article's subject is identical to the first part of another
- ! article, the two subjects will still be considered identical if the
- ! length of the shorter subject is at least the limit set by this
- ! variable. This is mainly used to get articles whose subject line has
- ! been truncated for some reason (who said notefiles?) aligned with the
- ! proper set of articles anyway.
- .TP
- \fBsubject-match-offset\fP \fIoffset\fP (integer, default 0)
- When set to a positive number, that many characters at the beginning
- --- 1101,1110 ----
- .B n
- command).
- .TP
- ! \fBsubject-match-limit\fP \fIlength\fP (integer, default 256)
- ! Subjects will be considered identical if their first \fIlength\fP
- ! characters match. Setting this uncritically to a low value may
- ! cause unexpected results!
- .TP
- \fBsubject-match-offset\fP \fIoffset\fP (integer, default 0)
- When set to a positive number, that many characters at the beginning
- *** ./LAST/more.c Tue Sep 18 12:45:08 1990
- --- more.c Thu Sep 20 22:05:48 1990
- ***************
- *** 1038,1043 ****
- --- 1038,1047 ----
- if (shell_escape()) goto redraw;
- goto dflt_prompt;
-
- + case K_VERSION:
- + prompt(P_VERSION);
- + goto same_prompt;
- +
- case K_EXTENDED_CMD:
- news_save = news;
- digest_save = digest;
- *** ./LAST/news.c Thu Jul 19 18:12:20 1990
- --- news.c Thu Sep 27 20:27:34 1990
- ***************
- *** 55,61 ****
- if (fptr = (*hdr_field)(bp, all)) {
- while (*bp && *bp != ':' && isascii(*bp) && !isspace(*bp))
- bp++;
- ! bp++;
- while (*bp && isascii(*bp) && isspace(*bp) && *bp != NL) bp++;
- *fptr = bp;
- }
- --- 55,61 ----
- if (fptr = (*hdr_field)(bp, all)) {
- while (*bp && *bp != ':' && isascii(*bp) && !isspace(*bp))
- bp++;
- ! if (*bp) bp++;
- while (*bp && isascii(*bp) && isspace(*bp) && *bp != NL) bp++;
- *fptr = bp;
- }
- *** ./LAST/newsrc.c Tue Sep 18 12:45:09 1990
- --- newsrc.c Thu Oct 4 22:30:46 1990
- ***************
- *** 26,31 ****
- --- 26,32 ----
-
- export int keep_rc_backup = 1;
- export char *bak_suffix = ".bak";
- + export char *initial_newsrc_path = ".defaultnewsrc";
-
- export int no_update = 0;
- export int use_selections = 1;
- ***************
- *** 337,343 ****
- }
-
- rc = open_file(newsrc_file, OPEN_READ);
- ! if (rc == NULL) goto new_user;
-
- while (fgets(rcbuf, RC_LINE_MAX, rc) != NULL) {
- gh = NULL;
- --- 338,351 ----
- }
-
- rc = open_file(newsrc_file, OPEN_READ);
- ! if (rc == NULL) {
- ! extern FILE *open_file_search_path();
- ! rc = open_file_search_path(initial_newsrc_path, OPEN_READ);
- ! if (rc == NULL) goto new_user;
- ! /* ignore groups not in the initial newsrc file */
- ! last_new_gh = ACTIVE_GROUP(master.number_of_groups - 1);
- ! last_new_group = last_new_gh->creation_time;
- ! }
-
- while (fgets(rcbuf, RC_LINE_MAX, rc) != NULL) {
- gh = NULL;
- *** ./LAST/nntp.c Thu Jul 19 18:12:21 1990
- --- nntp.c Fri Oct 5 18:23:22 1990
- ***************
- *** 47,53 ****
- import char *db_directory, *tmp_directory, *news_active;
-
- export char nntp_server[256]; /* name of nntp server */
- - export int use_nntp = 0; /* bool: t iff we use nntp */
- export int nntp_failed = 0; /* bool: t iff connection is broken in
- nntp_get_article() or nntp_get_active() */
-
- --- 47,52 ----
- ***************
- *** 63,68 ****
- --- 62,68 ----
- import char *sys_errlist[];
- extern int user_error();
- extern int sys_error();
- + extern int sys_warning();
-
- #define syserr() (errno >= 0 && errno < sys_nerr ? \
- sys_errlist[errno] : "Unknown error.")
- ***************
- *** 259,265 ****
- /*
- * get_socket: get a connection to the nntp server.
- *
- ! * Doesn't return in case of errors.
- */
-
- static get_socket()
- --- 259,268 ----
- /*
- * get_socket: get a connection to the nntp server.
- *
- ! * Errors can happen when YP services or DNS are temporarily down or
- ! * hung, so we log errors and return failure rather than exitting if we
- ! * are the master. The effects of retrying every 15 minutes (or whatever
- ! * the -r interval is) are not that bad. Dave Olson, SGI
- */
-
- static get_socket()
- ***************
- *** 276,287 ****
- #endif
-
- if ((sp = getservbyname("nntp", "tcp")) == NULL)
- ! sys_error("nntp/tcp: Unknown service.\n");
-
- s = who_am_i == I_AM_MASTER ? 10 : 2;
- while ((hp = gethostbyname(nntp_server)) == NULL) {
- ! if (--s < 0)
- ! sys_error("NNTP server %s unknown.\n", nntp_server);
- sleep(10);
- }
-
- --- 279,289 ----
- #endif
-
- if ((sp = getservbyname("nntp", "tcp")) == NULL)
- ! return sys_warning("nntp/tcp: Unknown service.\n");
-
- s = who_am_i == I_AM_MASTER ? 10 : 2;
- while ((hp = gethostbyname(nntp_server)) == NULL) {
- ! if (--s < 0) goto host_err;
- sleep(10);
- }
-
- ***************
- *** 300,309 ****
- #ifdef h_addr
- /* get a socket and initiate connection -- use multiple addresses */
-
- for (cp = hp->h_addr_list; cp && *cp; cp++) {
- s = socket(hp->h_addrtype, SOCK_STREAM, 0);
- ! if (s < 0)
- ! sys_error("Can't get NNTP socket: %s\n", syserr());
- bcopy(*cp, (char *)&sin.sin_addr, hp->h_length);
-
- x = connect(s, (struct sockaddr *)&sin, sizeof (sin));
- --- 302,311 ----
- #ifdef h_addr
- /* get a socket and initiate connection -- use multiple addresses */
-
- + s = x = -1;
- for (cp = hp->h_addr_list; cp && *cp; cp++) {
- s = socket(hp->h_addrtype, SOCK_STREAM, 0);
- ! if (s < 0) goto sock_err;
- bcopy(*cp, (char *)&sin.sin_addr, hp->h_length);
-
- x = connect(s, (struct sockaddr *)&sin, sizeof (sin));
- ***************
- *** 314,352 ****
- (void) close(s);
- s = -1;
- }
- ! if (x < 0 && who_am_i != I_AM_MASTER)
- ! user_error("Giving up on NNTP server %s!\n", nntp_server);
- #else /* no name server */
- #ifdef EXCELAN
- if ((s = socket(SOCK_STREAM, NULL, &sin, SO_KEEPALIVE)) < 0)
- ! sys_error("Can't get NNTP socket: %s", syserr());
- !
- sin.sin_port = htons(IPPORT_NNTP);
- machine = nntp_server;
- ! if ((sin.sin_addr.s_addr = rhost(&machine)) == -1)
- ! sys_error("%s: Unknown host.", nntp_server);
-
- /* And then connect */
- ! if (connect(s, &sin) < 0) {
- ! if (who_am_i == I_AM_MASTER)
- ! sys_error("Connecting to %s: %s", nntp_server, syserr());
- ! (void) close(s);
- ! s = -1;
- ! }
- #else /* not EXCELAN */
- if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
- ! sys_error("Can't get NNTP socket: %s\n", syserr());
- !
- /* And then connect */
- bcopy(hp->h_addr, (char *) &sin.sin_addr, hp->h_length);
- ! if (connect(s, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
- ! if (who_am_i == I_AM_MASTER)
- ! sys_error("Connecting to %s failed: %s", nntp_server, syserr());
- ! s = -1;
- ! }
- #endif /* EXCELAN */
- #endif
- return s;
- }
-
- /*
- --- 316,363 ----
- (void) close(s);
- s = -1;
- }
- ! if (x < 0)
- ! sys_warning("Giving up on NNTP server %s!", nntp_server);
- #else /* no name server */
- #ifdef EXCELAN
- if ((s = socket(SOCK_STREAM, NULL, &sin, SO_KEEPALIVE)) < 0)
- ! goto sock_err;
- !
- sin.sin_port = htons(IPPORT_NNTP);
- machine = nntp_server;
- ! if ((sin.sin_addr.s_addr = rhost(&machine)) == -1) {
- ! (void) close(s);
- ! goto host_err;
- ! }
-
- /* And then connect */
- ! if (connect(s, &sin) < 0)
- ! goto conn_err;
- #else /* not EXCELAN */
- if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
- ! goto sock_err;
- !
- /* And then connect */
- bcopy(hp->h_addr, (char *) &sin.sin_addr, hp->h_length);
- ! if (connect(s, (struct sockaddr *) &sin, sizeof(sin)) < 0)
- ! goto conn_err;
- #endif /* EXCELAN */
- #endif
- return s;
- +
- + host_err:
- + sys_warning("NNTP server %s unknown.\n", nntp_server);
- + return -1;
- +
- + sock_err:
- + sys_warning("Can't get NNTP socket: %s", syserr());
- + return -1;
- +
- + conn_err:
- + (void) close(s);
- + if (who_am_i == I_AM_MASTER)
- + sys_warning("Connecting to %s failed: %s", nntp_server, syserr());
- + return -1;
- }
-
- /*
- *** ./LAST/patchlevel.h Tue Sep 18 12:45:13 1990
- --- patchlevel.h Thu Oct 4 23:12:18 1990
- ***************
- *** 21,27 ****
- * 1990-07-16: Patch #8 (6.4.8) - HIGH
- * 1990-07-19: Patch #9 (6.4.9) - MEDIUM
- * 1990-09-18: Patch #10 (6.4.10) - HIGH
- */
-
- ! #define PATCHLEVEL 10
-
- --- 21,28 ----
- * 1990-07-16: Patch #8 (6.4.8) - HIGH
- * 1990-07-19: Patch #9 (6.4.9) - MEDIUM
- * 1990-09-18: Patch #10 (6.4.10) - HIGH
- + * 1990-10-05: Patch #11 (6.4.11) - HIGH
- */
-
- ! #define PATCHLEVEL 11
-
- *** ./LAST/save.c Tue Sep 18 12:45:14 1990
- --- save.c Mon Oct 1 17:15:46 1990
- ***************
- *** 22,27 ****
- --- 22,28 ----
- export int quick_save = 0;
- export int conf_append = 0;
- export int conf_create = 1;
- + export int folder_format_check = 1;
-
- export char *saved_header_escape = "~";
-
- ***************
- *** 47,52 ****
- --- 48,55 ----
- import int shell_restrictions;
- import char delayed_msg[];
-
- + import int current_folder_type;
- +
- import int rot13_active;
-
- static int save_mode;
- ***************
- *** 151,156 ****
- --- 154,173 ----
- return 1;
- }
-
- + set_folder_type(name)
- + char *name;
- + {
- + FILE *f;
- +
- + current_folder_type = -1;
- + if (!folder_format_check) return;
- +
- + if ((f = open_file(name, OPEN_READ)) != NULL) {
- + get_folder_type(f);
- + fclose(f);
- + }
- + }
- +
- char *init_save(command, mode_textp)
- char command;
- char **mode_textp;
- ***************
- *** 487,494 ****
- fclose(art);
- return 0;
- }
- ! if (ftell(save_file) != (off_t)0)
- save_mode &= ~FILE_IS_NEW;
- }
- }
-
- --- 504,514 ----
- fclose(art);
- return 0;
- }
- ! current_folder_type = -1;
- ! if (ftell(save_file) != (off_t)0) {
- ! if (mode != NO_HEADER) set_folder_type(save_name);
- save_mode &= ~FILE_IS_NEW;
- + }
- }
- }
-
- ***************
- *** 627,632 ****
- --- 647,656 ----
- return;
- }
- fseek(h, (off_t)0, 2);
- + if (ftell(h) > 0)
- + set_folder_type(file);
- + else
- + current_folder_type = -1;
- if (!use_mmdf_folders && ftell(h) > 0) putc(NL, h); /* just in case */
- mailbox_format(h, 1);
- endpos = ftell(f) - ah->hpos;
- ***************
- *** 644,651 ****
- {
- time_t now;
- char *ctime();
-
- ! if (use_mmdf_folders) {
- fprintf(f, "\001\001\001\001\n");
- return 0;
- }
- --- 668,692 ----
- {
- time_t now;
- char *ctime();
- + int do_mmdf, do_mail;
- +
- + do_mmdf = do_mail = 0;
- + switch (current_folder_type) {
- + case 0:
- + break;
- + case 1:
- + do_mail = 1;
- + break;
- + case 2:
- + do_mmdf = 1;
- + break;
- + default:
- + do_mmdf = use_mmdf_folders;
- + do_mail = use_mail_folders;
- + break;
- + }
-
- ! if (do_mmdf) {
- fprintf(f, "\001\001\001\001\n");
- return 0;
- }
- ***************
- *** 655,661 ****
- return 1;
- }
-
- ! if (use_mail_folders) {
- now = cur_time();
- fprintf(f, "From %s %s",
- (use_path_in_from && news.ng_path) ? news.ng_path :
- --- 696,702 ----
- return 1;
- }
-
- ! if (top > 0 && do_mail) {
- now = cur_time();
- fprintf(f, "From %s %s",
- (use_path_in_from && news.ng_path) ? news.ng_path :
- *** ./LAST/sequence.c Tue Sep 18 12:45:14 1990
- --- sequence.c Wed Sep 19 18:40:55 1990
- ***************
- *** 669,674 ****
- --- 669,675 ----
-
- case GS_NEW_GROUP:
- if ((gh->group_flag & G_NEW) == 0) continue;
- + if (gh->group_flag & G_UNSUBSCRIBED) continue;
- break;
-
- case GS_PREFIX0:
- *** ./LAST/sort.c Tue Sep 18 12:45:15 1990
- --- sort.c Thu Oct 4 22:27:30 1990
- ***************
- *** 9,15 ****
- --- 9,24 ----
-
-
-
- + #ifdef BAD_ORDER_SUBJ_DATE
- + /* If one article's subject is identical to the first part of another
- + article, the two subjects will still be considered identical if the
- + length of the shorter subject is at least the limit set by this variable. */
- export int subject_match_limit = 20; /* "strncmp" limit for subjects */
- + #else
- + /* Subjects are considered identical if their first s-m-l characters match */
- + export int subject_match_limit = 256; /* "strncmp" limit for subjects */
- + #endif
- +
- export int match_skip_prefix = 0; /* skip first N bytes in matches */
- export int match_parts_equal = 0; /* match digits as equal */
-
- ***************
- *** 78,95 ****
- --- 87,112 ----
- }
- }
-
- + #ifdef BAD_ORDER_SUBJ_DATE
- for (len = 0; ; len++, a++, b++) {
- + #else
- + for (len = subject_match_limit; --len >= 0; a++, b++) {
- + #endif
- while ((ca = *a) && MATCH_DROP(match_subject, ca)) a++;
- while ((cb = *b) && MATCH_DROP(match_subject, cb)) b++;
-
- if (ca == NUL) {
- if (cb == NUL) break;
- + #ifdef BAD_ORDER_SUBJ_DATE
- if (len >= subject_match_limit) break;
- + #endif
- return -1;
- }
-
- if (cb == NUL) {
- + #ifdef BAD_ORDER_SUBJ_DATE
- if (len >= subject_match_limit) break;
- + #endif
- return 1;
- }
-
- *** ./LAST/term.c Tue Sep 18 12:45:16 1990
- --- term.c Tue Sep 18 15:33:39 1990
- ***************
- *** 825,832 ****
- --- 825,834 ----
- do_flush_input = 1;
- #else
- #ifdef FREAD
- + {
- int arg = FREAD;
- ioctl(0, TIOCFLUSH, &arg);
- + }
- #else
- ioctl(0, TIOCFLUSH, 0);
- #endif
- *** ./LAST/variable.c Tue Sep 18 12:45:17 1990
- --- variable.c Thu Oct 4 23:12:16 1990
- ***************
- *** 11,16 ****
- --- 11,17 ----
- import in_init;
-
- import char /* string variables */
- + *backup_folder_path,
- *bak_suffix,
- *bug_address,
- *decode_header_file,
- ***************
- *** 26,31 ****
- --- 27,33 ----
- *folder_directory,
- included_mark[],
- *inews_program,
- + *initial_newsrc_path,
- *mail_box,
- *mail_record,
- *mail_script,
- ***************
- *** 60,65 ****
- --- 62,68 ----
- auto_select_subject,
- auto_preview_mode,
- case_fold_search,
- + check_group_access,
- compress_mode,
- conf_append,
- conf_auto_quit,
- ***************
- *** 81,91 ****
- --- 84,97 ----
- flow_control,
- flush_typeahead,
- fmt_rptsubj,
- + folder_format_check,
- + folder_rewrite_trace,
- ignore_xon_xoff,
- include_art_id,
- include_full_header,
- include_mark_blanks,
- inews_pipe_input,
- + keep_backup_folder,
- keep_rc_backup,
- keep_unsubscribed,
- keep_unsub_long,
- ***************
- *** 163,168 ****
- --- 169,175 ----
- scroll_last_lines,
- show_purpose_mode,
- slow_speed,
- + strict_from_parse,
- sort_mode,
- subject_match_limit,
- wrap_headers;
- ***************
- *** 200,205 ****
- --- 207,213 ----
- #define V_SAFE 0x0100
- #define V_INIT 0x0200
-
- + #define V_LOCKED 0x0800
- #define V_MODIFIED 0x8000
-
- #define STR V_STRING |
- ***************
- *** 232,240 ****
- --- 240,250 ----
- "auto-read-mode-limit", INT 0, (char **)&auto_read_limit,
- "auto-select-subject", BOOL 0, (char **)&auto_select_subject,
- "backup", BOOL 0, (char **)&keep_rc_backup,
- + "backup-folder-path", STR 4, (char **)&backup_folder_path,
- "backup-suffix", STR 0, (char **)&bak_suffix,
- "bug-report-address", STR 0, (char **)&bug_address,
- "case-fold-search", BOOL 0, (char **)&case_fold_search,
- + "check-group-access", BOOL 0, (char **)&check_group_access,
- "collapse-subject", INT 3, (char **)&collapse_subject,
- "columns", INT 1, (char **)&Columns,
- "comp1-key", KEY 0, (char **)&comp1_key,
- ***************
- *** 272,279 ****
- --- 282,291 ----
- "flow-control", BOOL 0, (char **)&flow_control,
- "flush-typeahead", BOOL 0, (char **)&flush_typeahead,
- "folder", STR 2, (char **)&folder_directory,
- + "folder-format-check", BOOL 0, (char **)&folder_format_check,
- "folder-save-file", STR 3, (char **)&folder_save_file,
- "follow-distribution", STR 0, (char **)&distribution_follow,
- + "from-line-parsing", INT 0, (char **)&strict_from_parse,
- "fsort", BOOL 2, (char **)&dont_sort_folders,
- "header-lines", STR 0, (char **)&header_lines,
- "help-key", KEY 0, (char **)&help_key,
- ***************
- *** 284,289 ****
- --- 296,303 ----
- "included-mark", STR 1, (char **)included_mark,
- "inews", STR 0, (char **)&inews_program,
- "inews-pipe-input", BOOL 0, (char **)&inews_pipe_input,
- + "initial-newsrc-file", STR 0, (char **)&initial_newsrc_path,
- + "keep-backup-folder", BOOL 0, (char **)&keep_backup_folder,
- "keep-unsubscribed", BOOL 0, (char **)&keep_unsubscribed,
- "kill", BOOL 0, (char **)&do_kill_handling,
- "kill-debug", BOOL 0, (char **)&kill_debug,
- ***************
- *** 375,380 ****
- --- 389,395 ----
- "suggest-default-save", BOOL 0, (char **)&suggest_save_file,
- "tidy-newsrc", BOOL 0, (char **)&tidy_newsrc,
- "time", BOOL 0, (char **)&show_current_time,
- + "trace-folder-packing", BOOL 0, (char **)&folder_rewrite_trace,
- "trusted-escape-codes", STR 0, (char **)&trusted_escapes,
- "unshar-command", STR SAFE 1, (char **)unshar_command,
- "unshar-header-file", STR 0, (char **)&unshar_header_file,
- ***************
- *** 496,501 ****
- --- 511,521 ----
- }
- }
-
- + if (var->var_flags & V_LOCKED) {
- + msg("Variable '%s' is locked", variable);
- + return 0;
- + }
- +
- if (!on || val_string == NULL)
- value = 0;
- else
- ***************
- *** 531,540 ****
- --- 551,568 ----
- break;
-
- case 3:
- + case 4:
- if (!on || val_string == NULL) {
- msg("Cannot unset string `%s'", variable);
- break;
- }
- + if (VAR_OP == 4) {
- + char exp_buf[FILENAME];
- + if (expand_file_name(exp_buf, val_string, 1)) {
- + STR_VAR = copy_str(exp_buf);
- + break;
- + }
- + }
- STR_VAR = copy_str(val_string);
- break;
- }
- ***************
- *** 670,675 ****
- --- 698,712 ----
- BOOL_VAR = !BOOL_VAR;
- }
-
- + lock_variable(variable)
- + char *variable;
- + {
- + register struct variable_defs *var;
- +
- + if ((var = lookup_variable(variable)) != NULL)
- + var->var_flags |= V_LOCKED;
- + }
- +
-
- static char *var_value(var, tag)
- register struct variable_defs *var;
- ***************
- *** 681,686 ****
- --- 718,724 ----
-
- if (tag != NULL)
- *tag = var_on_stack(var) ? '>' :
- + (var->var_flags & V_LOCKED) ? '!' :
- (var->var_flags & V_MODIFIED) ? '*' : ' ';
-
- switch (VAR_TYPE) {
- ***************
- *** 898,903 ****
- --- 936,942 ----
- case 0: /* if we update one of these variables, */
- case 2: /* new storage will be allocated for it */
- case 3: /* so it is ok just to save the pointer */
- + case 4:
- vs->value.str = STR_VAR;
- break;
-
- ***************
- *** 956,961 ****
- --- 995,1001 ----
- case 0: /* only restore the string if changed; then we */
- case 2: /* can also free the memory occupied by the */
- case 3: /* 'new' value (if not NULL) */
- + case 4:
- if (STR_VAR != vs->value.str) {
- if (STR_VAR != NULL) freeobj(STR_VAR);
- STR_VAR = vs->value.str;
- *** ./LAST/xmakefile Tue Jun 12 11:47:04 1990
- --- xmakefile Wed Aug 22 20:16:40 1990
- ***************
- *** 24,29 ****
- --- 24,38 ----
- #define NNTP_EXTRA_LIB
- #endif
-
- + * Symmetry style parallel make
- +
- + #undef PARALLEL
- + #ifdef PARALLEL_MAKE
- + #define PARALLEL &
- + #else
- + #define PARALLEL
- + #endif
- +
- #ifdef HAVE_ROUTING
- #define NNMAIL
- #else
- ***************
- *** 53,59 ****
- *
-
- BIN_PROG = nn NNMAIL nnusage nngrab nnstats ACCOUNT
- ! BIN_LINK = nncheck nnadmin nntidy nngoback nngrep nnpost
- LIB_PROG = aux upgrade_rc
- MASTER_PROG = nnmaster back_act nnspew
-
- --- 62,68 ----
- *
-
- BIN_PROG = nn NNMAIL nnusage nngrab nnstats ACCOUNT
- ! BIN_LINK = nncheck nnadmin nntidy nngoback nngrep nnpost nnbatch
- LIB_PROG = aux upgrade_rc
- MASTER_PROG = nnmaster back_act nnspew
-
- ***************
- *** 85,99 ****
-
- master: $(MASTER_PROG) inst
-
- ! nn: $(NN)
- @echo linking nn
- @$(CC) $(CFLAGS) $(NN) -o nn TERMLIB EXTRA_LIB NNTP_EXTRA_LIB
-
- ! nnmaster: $(MASTER)
- @echo linking nnmaster
- @$(CC) $(CFLAGS) $(MASTER) -o nnmaster EXTRA_LIB NNTP_EXTRA_LIB
-
- ! nnmail: $(MAIL)
- @echo linking nnmail
- @$(CC) $(CFLAGS) $(MAIL) EXTRA_LIB -o nnmail
-
- --- 94,108 ----
-
- master: $(MASTER_PROG) inst
-
- ! nn: PARALLEL $(NN)
- @echo linking nn
- @$(CC) $(CFLAGS) $(NN) -o nn TERMLIB EXTRA_LIB NNTP_EXTRA_LIB
-
- ! nnmaster: PARALLEL $(MASTER)
- @echo linking nnmaster
- @$(CC) $(CFLAGS) $(MASTER) -o nnmaster EXTRA_LIB NNTP_EXTRA_LIB
-
- ! nnmail: PARALLEL $(MAIL)
- @echo linking nnmail
- @$(CC) $(CFLAGS) $(MAIL) EXTRA_LIB -o nnmail
-
- ***************
- *** 112,118 ****
- upgrade_rc: upgrade_rc.sh prefix
- cat prefix upgrade_rc.sh > upgrade_rc ; chmod +x upgrade_rc
-
- ! nnacct: $(ACCT)
- @echo linking nnacct
- @$(CC) $(CFLAGS) $(ACCT) EXTRA_LIB -o nnacct
-
- --- 121,127 ----
- upgrade_rc: upgrade_rc.sh prefix
- cat prefix upgrade_rc.sh > upgrade_rc ; chmod +x upgrade_rc
-
- ! nnacct: PARALLEL $(ACCT)
- @echo linking nnacct
- @$(CC) $(CFLAGS) $(ACCT) EXTRA_LIB -o nnacct
-
- ***************
- *** 125,131 ****
- prefix: config.h mkprefix
- ./mkprefix prefix < /dev/null > prefix
-
- ! mkprefix: prefix.o global.o
- $(CC) $(CFLAGS) prefix.o global.o EXTRA_LIB -o mkprefix
-
- *
- --- 134,140 ----
- prefix: config.h mkprefix
- ./mkprefix prefix < /dev/null > prefix
-
- ! mkprefix: PARALLEL prefix.o global.o
- $(CC) $(CFLAGS) prefix.o global.o EXTRA_LIB -o mkprefix
-
- *
-